﻿using System;
using Microsoft.Xna.Framework.Graphics;

namespace Ferpect.ComponentModel.Utilities
{
    public static class RenderTargets
    {
        public static RenderTarget2D CreateRenderTarget(GraphicsDevice device, int numberLevels, SurfaceFormat surface)
        {
            MultiSampleType type = device.PresentationParameters.MultiSampleType;

            // If the card can't use the surface format
            if (!GraphicsAdapter.DefaultAdapter.CheckDeviceFormat(
                    DeviceType.Hardware,
                    GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Format,
                    TextureUsage.None,
                    QueryUsages.None,
                    ResourceType.RenderTarget,
                    surface))
            {
                // Fall back to current display format
                surface = device.DisplayMode.Format;
            }
            // Or it can't accept that surface format 
            // with the current AA settings
            else if (!GraphicsAdapter.DefaultAdapter.CheckDeviceMultiSampleType(
                    DeviceType.Hardware,
                    surface,
                    device.PresentationParameters.IsFullScreen,
                    type))
            {
                // Fall back to no antialiasing
                type = MultiSampleType.None;
            }

            int width, height;

            // See if we can use our buffer size as our texture
            CheckTextureSize(device.PresentationParameters.BackBufferWidth,
                             device.PresentationParameters.BackBufferHeight,
                             out width,
                             out height);

            // Create our render target
            return new RenderTarget2D(device, width, height, numberLevels, surface, type, 0);
        }

        public static bool CheckTextureSize(int width, int height, out int newwidth, out int newheight)
        {
            bool retval = false;

            GraphicsDeviceCapabilities caps = GraphicsAdapter.DefaultAdapter.GetCapabilities(DeviceType.Hardware);

            if (caps.TextureCapabilities.RequiresPower2)
            {
                retval = true;  // Return true to indicate the numbers changed

                // Find the nearest base two log of the current width, 
                // and go up to the next integer                
                double exp = Math.Ceiling(Math.Log(width) / Math.Log(2));
                // and use that as the exponent of the new width
                width = (int)Math.Pow(2, exp);
                // Repeat the process for height
                exp = Math.Ceiling(Math.Log(height) / Math.Log(2));
                height = (int)Math.Pow(2, exp);
            }
            if (caps.TextureCapabilities.RequiresSquareOnly)
            {
                retval = true;  // Return true to indicate numbers changed
                width = Math.Max(width, height);
                height = width;
            }

            newwidth = Math.Min(caps.MaxTextureWidth, width);
            newheight = Math.Min(caps.MaxTextureHeight, height);
            return retval;
        }


    }
}
